/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package wggcth.persistencia.controle;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import wggcth.persistencia.controle.exceptions.IllegalOrphanException;
import wggcth.persistencia.controle.exceptions.NonexistentEntityException;
import wggcth.persistencia.vo.Experimento;
import java.util.ArrayList;
import java.util.Collection;
import wggcth.persistencia.vo.Usuario;

/**
 *
 * @author deusemar
 */
public class UsuarioJpaController {

    public UsuarioJpaController() {
        emf = Persistence.createEntityManagerFactory("wggcthPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Usuario usuario) {
        if (usuario.getExperimentoCollection() == null) {
            usuario.setExperimentoCollection(new ArrayList<Experimento>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Collection<Experimento> attachedExperimentoCollection = new ArrayList<Experimento>();
            for (Experimento experimentoCollectionExperimentoToAttach : usuario.getExperimentoCollection()) {
                experimentoCollectionExperimentoToAttach = em.getReference(experimentoCollectionExperimentoToAttach.getClass(), experimentoCollectionExperimentoToAttach.getIdexperimento());
                attachedExperimentoCollection.add(experimentoCollectionExperimentoToAttach);
            }
            usuario.setExperimentoCollection(attachedExperimentoCollection);
            em.persist(usuario);
            for (Experimento experimentoCollectionExperimento : usuario.getExperimentoCollection()) {
                Usuario oldIdusuarioOfExperimentoCollectionExperimento = experimentoCollectionExperimento.getIdusuario();
                experimentoCollectionExperimento.setIdusuario(usuario);
                experimentoCollectionExperimento = em.merge(experimentoCollectionExperimento);
                if (oldIdusuarioOfExperimentoCollectionExperimento != null) {
                    oldIdusuarioOfExperimentoCollectionExperimento.getExperimentoCollection().remove(experimentoCollectionExperimento);
                    oldIdusuarioOfExperimentoCollectionExperimento = em.merge(oldIdusuarioOfExperimentoCollectionExperimento);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Usuario usuario) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario persistentUsuario = em.find(Usuario.class, usuario.getIdusuario());
            Collection<Experimento> experimentoCollectionOld = persistentUsuario.getExperimentoCollection();
            Collection<Experimento> experimentoCollectionNew = usuario.getExperimentoCollection();
            List<String> illegalOrphanMessages = null;
            for (Experimento experimentoCollectionOldExperimento : experimentoCollectionOld) {
                if (!experimentoCollectionNew.contains(experimentoCollectionOldExperimento)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Experimento " + experimentoCollectionOldExperimento + " since its idusuario field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Collection<Experimento> attachedExperimentoCollectionNew = new ArrayList<Experimento>();
            for (Experimento experimentoCollectionNewExperimentoToAttach : experimentoCollectionNew) {
                experimentoCollectionNewExperimentoToAttach = em.getReference(experimentoCollectionNewExperimentoToAttach.getClass(), experimentoCollectionNewExperimentoToAttach.getIdexperimento());
                attachedExperimentoCollectionNew.add(experimentoCollectionNewExperimentoToAttach);
            }
            experimentoCollectionNew = attachedExperimentoCollectionNew;
            usuario.setExperimentoCollection(experimentoCollectionNew);
            usuario = em.merge(usuario);
            for (Experimento experimentoCollectionNewExperimento : experimentoCollectionNew) {
                if (!experimentoCollectionOld.contains(experimentoCollectionNewExperimento)) {
                    Usuario oldIdusuarioOfExperimentoCollectionNewExperimento = experimentoCollectionNewExperimento.getIdusuario();
                    experimentoCollectionNewExperimento.setIdusuario(usuario);
                    experimentoCollectionNewExperimento = em.merge(experimentoCollectionNewExperimento);
                    if (oldIdusuarioOfExperimentoCollectionNewExperimento != null && !oldIdusuarioOfExperimentoCollectionNewExperimento.equals(usuario)) {
                        oldIdusuarioOfExperimentoCollectionNewExperimento.getExperimentoCollection().remove(experimentoCollectionNewExperimento);
                        oldIdusuarioOfExperimentoCollectionNewExperimento = em.merge(oldIdusuarioOfExperimentoCollectionNewExperimento);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = usuario.getIdusuario();
                if (findUsuario(id) == null) {
                    throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario usuario;
            try {
                usuario = em.getReference(Usuario.class, id);
                usuario.getIdusuario();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Collection<Experimento> experimentoCollectionOrphanCheck = usuario.getExperimentoCollection();
            for (Experimento experimentoCollectionOrphanCheckExperimento : experimentoCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Usuario (" + usuario + ") cannot be destroyed since the Experimento " + experimentoCollectionOrphanCheckExperimento + " in its experimentoCollection field has a non-nullable idusuario field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            em.remove(usuario);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }


   public Usuario findByEmail( String email) {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
	final String queryString = "select model from Usuario model where model.email =:email ";
	Query query = em.createQuery(queryString);
	query.setParameter("email", email.toLowerCase());

        return (Usuario) query.getSingleResult() ;
        }catch (RuntimeException e) {
            return  null;
        }  finally {
            em.close();
        }
    }
    public List<Usuario> findUsuarioEntities() {
        return findUsuarioEntities(true, -1, -1);
    }

    public List<Usuario> findUsuarioEntities(int maxResults, int firstResult) {
        return findUsuarioEntities(false, maxResults, firstResult);
    }

    private List<Usuario> findUsuarioEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from Usuario as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Usuario findUsuario(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Usuario.class, id);
        } finally {
            em.close();
        }
    }

    public int getUsuarioCount() {
        EntityManager em = getEntityManager();
        try {
            return ((Long) em.createQuery("select count(o) from Usuario as o").getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
